home *** CD-ROM | disk | FTP | other *** search
/ Celestin Apprentice 4 / Apprentice-Release4.iso / Source Code / Libraries / Apache 1.0 / src / util_script.c < prev    next >
Text File  |  1995-12-04  |  8KB  |  260 lines

  1.  
  2. /* ====================================================================
  3.  * Copyright (c) 1995 The Apache Group.  All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * 1. Redistributions of source code must retain the above copyright
  10.  *    notice, this list of conditions and the following disclaimer. 
  11.  *
  12.  * 2. Redistributions in binary form must reproduce the above copyright
  13.  *    notice, this list of conditions and the following disclaimer in
  14.  *    the documentation and/or other materials provided with the
  15.  *    distribution.
  16.  *
  17.  * 3. All advertising materials mentioning features or use of this
  18.  *    software must display the following acknowledgment:
  19.  *    "This product includes software developed by the Apache Group
  20.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  21.  *
  22.  * 4. The names "Apache Server" and "Apache Group" must not be used to
  23.  *    endorse or promote products derived from this software without
  24.  *    prior written permission.
  25.  *
  26.  * 5. Redistributions of any form whatsoever must retain the following
  27.  *    acknowledgment:
  28.  *    "This product includes software developed by the Apache Group
  29.  *    for use in the Apache HTTP server project (http://www.apache.org/)."
  30.  *
  31.  * THIS SOFTWARE IS PROVIDED BY THE APACHE GROUP ``AS IS'' AND ANY
  32.  * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  33.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  34.  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE APACHE GROUP OR
  35.  * IT'S CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  36.  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  37.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  38.  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  39.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
  40.  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
  41.  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
  42.  * OF THE POSSIBILITY OF SUCH DAMAGE.
  43.  * ====================================================================
  44.  *
  45.  * This software consists of voluntary contributions made by many
  46.  * individuals on behalf of the Apache Group and was originally based
  47.  * on public domain software written at the National Center for
  48.  * Supercomputing Applications, University of Illinois, Urbana-Champaign.
  49.  * For more information on the Apache Group and the Apache HTTP server
  50.  * project, please see <http://www.apache.org/>.
  51.  *
  52.  */
  53.  
  54.  
  55.  
  56. #include "httpd.h"
  57. #include "http_main.h"
  58. #include "http_log.h"
  59. #include "http_protocol.h"
  60. #include "http_core.h"        /* For document_root.  Sigh... */
  61. #include "util_script.h"
  62.  
  63. /*
  64.  * Various utility functions which are common to a whole lot of
  65.  * script-type extensions mechanisms, and might as well be gathered
  66.  * in one place (if only to avoid creating inter-module dependancies
  67.  * where there don't have to be).
  68.  */
  69.  
  70. char **create_argv(pool *p, char *av0, char *args) {
  71.     register int x,n;
  72.     char **av;
  73.     char *w;
  74.  
  75.     for(x=0,n=2;args[x];x++)
  76.         if(args[x] == '+') ++n;
  77.  
  78.     av = (char **)palloc(p, (n+1)*sizeof(char *));
  79.     av[0] = av0;
  80.  
  81.     for(x=1;x<n;x++) {
  82.         w = getword(p, &args, '+');
  83.         unescape_url(w);
  84.         av[x] = escape_shell_cmd(p, w);
  85.     }
  86.     av[n] = NULL;
  87.     return av;
  88. }
  89.  
  90. static char *http2env(pool *a, char *w)
  91. {
  92.     char *res = pstrcat (a, "HTTP_", w, NULL);
  93.     char *cp = res;
  94.   
  95.     while (*++cp)
  96.       if (*cp == '-') *cp = '_';
  97.       else *cp = toupper(*cp);
  98.  
  99.     return res;
  100. }
  101.  
  102. char **create_environment(pool *p, table *t)
  103. {
  104.     array_header *env_arr = table_elts (t);
  105.     table_entry *elts = (table_entry *)env_arr->elts;
  106.     char **env = (char **)palloc (p, (env_arr->nelts + 2) *sizeof (char *));
  107.     int i, j;
  108.     char *tz;
  109.  
  110.     j = 0;
  111.     tz = getenv("TZ");
  112.     if (tz!= NULL) env[j++] = pstrcat(p, "TZ=", tz, NULL);
  113.     for (i = 0; i < env_arr->nelts; ++i) {
  114.         if (!elts[i].key) continue;
  115.     env[j++] = pstrcat (p, elts[i].key, "=", elts[i].val, NULL);
  116.     }
  117.  
  118.     env[j] = NULL;
  119.     return env;
  120. }
  121.  
  122. void add_common_vars(request_rec *r)
  123. {
  124.     table *e = r->subprocess_env;
  125.     server_rec *s = r->server;
  126.     conn_rec *c = r->connection;
  127.     
  128.     char port[40],*env_path;
  129.     
  130.     array_header *hdrs_arr = table_elts (r->headers_in);
  131.     table_entry *hdrs = (table_entry *)hdrs_arr->elts;
  132.     int i;
  133.     
  134.     /* First, add environment vars from headers... this is as per
  135.      * CGI specs, though other sorts of scripting interfaces see
  136.      * the same vars...
  137.      */
  138.     
  139.     for (i = 0; i < hdrs_arr->nelts; ++i) {
  140.         if (!hdrs[i].key) continue;
  141.  
  142.     /* A few headers are special cased --- Authorization to prevent
  143.      * rogue scripts from capturing passwords; content-type and -length
  144.      * for no particular reason.
  145.      */
  146.     
  147.     if (!strcasecmp (hdrs[i].key, "Content-type")) 
  148.         table_set (e, "CONTENT_TYPE", hdrs[i].val);
  149.     else if (!strcasecmp (hdrs[i].key, "Content-length"))
  150.         table_set (e, "CONTENT_LENGTH", hdrs[i].val);
  151.     else if (!strcasecmp (hdrs[i].key, "Authorization"))
  152.         continue;
  153.     else
  154.         table_set (e, http2env (r->pool, hdrs[i].key), hdrs[i].val);
  155.     }
  156.     
  157.     sprintf(port, "%d", s->port);
  158.  
  159.     if(!(env_path = getenv("PATH")))
  160.         env_path=DEFAULT_PATH;
  161.     
  162.     table_set (e, "PATH", env_path);
  163.     table_set (e, "SERVER_SOFTWARE", SERVER_VERSION);
  164.     table_set (e, "SERVER_NAME", s->server_hostname);
  165.     table_set (e, "SERVER_PORT", port);
  166.     table_set (e, "REMOTE_HOST", c->remote_name);
  167.     table_set (e, "REMOTE_ADDR", c->remote_ip);
  168.     table_set (e, "DOCUMENT_ROOT", document_root(r)); /* Apache */
  169.     table_set (e, "SERVER_ADMIN", s->server_admin); /* Apache */
  170.     table_set (e, "SCRIPT_FILENAME", r->filename); /* Shambhala */
  171.     
  172.     if (c->user) table_set(e, "REMOTE_USER", c->user);
  173.     if (c->auth_type) table_set(e, "AUTH_TYPE", c->auth_type);
  174.     if (c->remote_logname) table_set(e, "REMOTE_IDENT", c->remote_logname);
  175.     
  176.     /* Apache custom error responses. If we have redirected set two new vars */
  177.     
  178.     if (r->prev) {
  179.         if (r->prev->args) table_set(e,"REDIRECT_QUERY_STRING", r->prev->args);
  180.     if (r->prev->uri) table_set (e, "REDIRECT_URL", r->prev->uri);
  181.     }
  182. }
  183.  
  184. int scan_script_header(request_rec *r, FILE *f)
  185. {
  186.     char w[MAX_STRING_LEN];
  187.     char *l;
  188.     int p;
  189.  
  190.     hard_timeout ("read script header", r);
  191.     
  192.     while(1) {
  193.  
  194.     if (fgets(w, MAX_STRING_LEN-1, f) == NULL) {
  195.         log_reason ("malformed header from script", r->filename, r);
  196.         return SERVER_ERROR;
  197.         }
  198.  
  199.     /* Delete terminal (CR?)LF */
  200.     
  201.     p = strlen(w);
  202.     if (p > 0 && w[p-1] == '\n')
  203.     {
  204.         if (p > 1 && w[p-2] == '\015') w[p-2] = '\0';
  205.         else w[p-1] = '\0';
  206.     }
  207.  
  208.         if(w[0] == '\0') {
  209.         kill_timeout (r);
  210.         return OK;
  211.     }
  212.                                    
  213.     /* if we see a bogus header don't ignore it. Shout and scream */
  214.     
  215.         if(!(l = strchr(w,':'))) {
  216.             /* Soak up all the script output --- may save an outright kill */
  217.         while (fgets(w, MAX_STRING_LEN-1, f) != NULL)
  218.             continue;
  219.         
  220.         kill_timeout (r);
  221.         log_reason ("malformed header from script", r->filename, r);
  222.         return SERVER_ERROR;
  223.         }
  224.  
  225.         *l++ = '\0';
  226.     while (*l && isspace (*l)) ++l;
  227.     
  228.         if(!strcasecmp(w,"Content-type")) {
  229.  
  230.         /* Nuke trailing whitespace */
  231.         
  232.         char *endp = l + strlen(l) - 1;
  233.         while (endp > l && isspace(*endp)) *endp-- = '\0';
  234.         
  235.         r->content_type = pstrdup (r->pool, l);
  236.     }
  237.         else if(!strcasecmp(w,"Status")) {
  238.             sscanf(l, "%d", &r->status);
  239.             r->status_line = pstrdup(r->pool, l);
  240.         }
  241.         else {
  242.         table_set (r->headers_out, w, l);
  243.         }
  244.     }
  245. }
  246.  
  247. void send_size(size_t size, request_rec *r) {
  248.     if(size == -1) 
  249.         rprintf (r, "    -");
  250.     else if(!size) 
  251.         rprintf (r, "   0K");
  252.     else if(size < 1024) 
  253.         rprintf(r, "   1K");
  254.     else if(size < 1048576)
  255.         rprintf(r, "%4dK", size / 1024);
  256.     else
  257.         rprintf(r, "%4dM", size / 1048576);
  258. }
  259.  
  260.